package cn.demoncat.util.pdf.itextpdf.entity;

import cn.demoncat.util.sec.entity.CertInfo;
import com.itextpdf.kernel.pdf.StampingProperties;
import com.itextpdf.signatures.PdfSigner;

import java.io.InputStream;
import java.io.OutputStream;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * PDF签章参数
 * 
 * @author 延晓磊
 *
 * @since 2020年6月6日
 */
public class PdfSignParam {

	/**
	 * 锻压模式：保留原始加密信息，可以追加签名
	 */
	public static StampingProperties STAMP_PROPERTIES = new StampingProperties().preserveEncryption().useAppendMode();
	
	/**
	 * 源PDF
	 */
	private InputStream src;
	/**
	 * 目标PDF
	 */
	private OutputStream out;
	/**
	 * 印章图片
	 */
	private byte[] img;

	/**
	 * 加密信息：私钥
	 */
	private PrivateKey pk;
	/**
	 * 加密信息：HASH算法
	 */
	private String algorithm;
	/**
	 * 加密信息：证书链
	 */
	private Certificate[] chain;

	/**
	 * 签名区
	 */
	private List<PdfSignArea> areas = new ArrayList<>();
	
	/**
	 * 总页数
	 */
	private Integer pageCount;

	/**
	 * 认证等级：0 签名，1 签名+禁止修改
	 */
	private int certificationLevel = 0;
	
	/**
	 * 构建
	 * 
	 * @param src	源PDF
	 * @param out	目标PDF
	 * @param img
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public static PdfSignParam build(InputStream src, OutputStream out, byte[] img) {
		PdfSignParam param = new PdfSignParam();
		param.setSrc(src);
		param.setOut(out);
		param.setImg(img);
		return param;
	}
	
	/**
	 * 设置源PDF
	 * 
	 * @param src	源PDF
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public PdfSignParam src(InputStream src) {
		this.src = src;
		return this;
	}
	
	/**
	 * 加密信息
	 * 
	 * @param pk		私钥
	 * @param algorithm	HASH算法
	 * @param chain		证书链
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public PdfSignParam addSign(PrivateKey pk, String algorithm, Certificate[] chain) {
		this.pk = pk;
		this.algorithm = algorithm;
		this.chain = chain;
		return this;
	}

	/**
	 * 加密信息
	 * 
	 * @param cert	证书信息：KeyToolUtil.read
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public PdfSignParam addSign(CertInfo cert) {
		return addSign(cert.getPrivateKey(), cert.getAlgorithm(), cert.getChain());
	}
	
	/**
	 * 签名区
	 * 
	 * @param areas
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public PdfSignParam addArea(PdfSignArea ...areas) {
		Collections.addAll(this.areas, areas);
		return this;
	}
	
	/**
	 * 设置总页数（签名区默认页码）
	 * 
	 * @param pageCount 总页数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public PdfSignParam pageCount(int pageCount) {
		this.pageCount = pageCount;
		return this;
	}
	
	/**
	 * 禁止更改
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年6月6日
	 */
	public PdfSignParam noChangeAllow() {
		this.certificationLevel = PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED;
		return this;
	}
	
	
	public InputStream getSrc() {
		return src;
	}

	public void setSrc(InputStream src) {
		this.src = src;
	}

	public OutputStream getOut() {
		return out;
	}

	public void setOut(OutputStream out) {
		this.out = out;
	}

	public byte[] getImg() {
		return img;
	}

	public void setImg(byte[] img) {
		this.img = img;
	}

	public PrivateKey getPk() {
		return pk;
	}

	public void setPk(PrivateKey pk) {
		this.pk = pk;
	}

	public String getAlgorithm() {
		return algorithm;
	}

	public void setAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}

	public Certificate[] getChain() {
		return chain;
	}

	public void setChain(Certificate[] chain) {
		this.chain = chain;
	}

	public List<PdfSignArea> getAreas() {
		return areas;
	}

	public void setAreas(List<PdfSignArea> areas) {
		this.areas = areas;
	}

	public Integer getPageCount() {
		return pageCount;
	}

	public void setPageCount(Integer pageCount) {
		this.pageCount = pageCount;
	}

	public int getCertificationLevel() {
		return certificationLevel;
	}

	public void setCertificationLevel(int certificationLevel) {
		this.certificationLevel = certificationLevel;
	}

}
